/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tardistv.controller;

import java.util.ArrayList;
import tardistv.model.Episode;
import tardistv.model.ListShowDownloadedEvent;
import tardistv.model.Show;
import tardistv.model.ShowFilledWithEpisodesEvent;

/**
 *
 * @author Carballude
 */
public class Controller {

    //Singleton pattern
    private static Controller INSTANCE = null;
        
    private ArrayList<ListShowDownloadedListener> listShowDownloadedListeners;
    private ArrayList<ShowFilledWithEpisodesListener> showFilledWithEpisodesListeners;

    /**
     * It's private because it's singleton
     */
    private Controller() {
        listShowDownloadedListeners = new ArrayList<ListShowDownloadedListener>();
        showFilledWithEpisodesListeners = new ArrayList<ShowFilledWithEpisodesListener>();
    }

    /**
     * Provides a single entry point to the class as a result of the Singleton implementation
     * @return The unique instance of the class
     */
    public static synchronized Controller getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Controller();
        }
        return INSTANCE;
    }

    /**
     * Adds listeners to its list of listeners
     * @param listener The listener to add
     */
    public void addListShowDownloadedListener(ListShowDownloadedListener listener) {
        if (!listShowDownloadedListeners.contains(listener)) {
            listShowDownloadedListeners.add(listener);
        }
    }

    public void addShowFilledWithEpisodesListener(ShowFilledWithEpisodesListener listener){
        if(!showFilledWithEpisodesListeners.contains(listener)){
            showFilledWithEpisodesListeners.add(listener);
        }
    }

    void listShowsDownloaded(ArrayList<Show> shows){
        addAvailableShows(shows);
        updateListShowDownloadListeners(new ListShowDownloadedEvent("",new DataBase().getAvailableShows()));
    }

    /**
     * Updates all its listeners with the new information of the event
     * @param event The event we want to inform about
     */
    private void updateListShowDownloadListeners(ListShowDownloadedEvent event) {
        addAvailableShows(event.getShows());
        for (ListShowDownloadedListener listener : listShowDownloadedListeners) {
            listener.listShowsDownloaded(event);
        }
    }

    private void updateShowFilledWithEpisodesListeners(ShowFilledWithEpisodesEvent event){
        for(ShowFilledWithEpisodesListener listener : showFilledWithEpisodesListeners){
            listener.showFilledWithEpisodes(event);
        }
    }

    /**
     * Starts the download of the available shows in a new thread
     */
    public void startDownloadingListShow() {
        new Thread(new TvCountDownShowListThread()).start();
    }

    /**
     * Gets the list of the subscribed shows.
     * @return A list with the subscribed shows, empty list if there's no subscription.
     */
    public ArrayList<Show> getSubscribedShows() {
        return new DataBase().getSubscribedShows();
    }

    public void addSubscriptionToShow(Show show){
        new DataBase().saveSubscribedShow(show);
    }

    private void addAvailableShows(ArrayList<Show> shows){
        new DataBase().saveAvailableShows(shows);
    }

    public Show getEpisodesForShow(Show show){
        Show filledShow = new DataBase().getEpisodes(show);
        new Thread(new TvCountDownFillEpisodes(show)).start();
        return filledShow;
    }

    void showFilledWithEpisodes(Show show){
        new DataBase().saveEpisodes(show);
        for(Episode episode : show.getEpisodes())
            if(episode.isAired())
                new Thread(new MininovaLookForEpisodeThread(episode));
        updateShowFilledWithEpisodesListeners(new ShowFilledWithEpisodesEvent(show, show));
    }
}
